package br3akr.DeadlyDinnerParty.Server.Actions;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;

import br3akr.DeadlyDinnerParty.Server.Engine.Session;
import br3akr.DeadlyDinnerParty.Server.Exceptions.DeadlyDinnerPartyException;
import br3akr.DeadlyDinnerParty.Server.World.Area;
import br3akr.DeadlyDinnerParty.Server.World.Chest;
import br3akr.DeadlyDinnerParty.Server.World.Exit;
import br3akr.DeadlyDinnerParty.Server.World.GameCharacter;
import br3akr.DeadlyDinnerParty.Server.World.Item;

public class DescribeAction extends Action {
	boolean actionComplete;
    private ActionResponse actionResponse;
    public static final Set<String> keywords;
	static
	{
		Set<String>tempKeywords = new HashSet<String>();
		tempKeywords.add("Describe");
		tempKeywords.add("Desc");
		tempKeywords.add("Look");
		keywords = Collections.unmodifiableSet(tempKeywords);
	}
    
    public DescribeAction() {
        super("Describe", true);
    }
    
    public ActionResponse doAction(String action, Session session) throws DeadlyDinnerPartyException {
		if (action == null) {
			throw new DeadlyDinnerPartyException ("No action found.");
		}
		if (session == null) {
			throw new DeadlyDinnerPartyException ("No session found.");
		}
    	StringTokenizer tokenizedAction = new StringTokenizer(action);
    	String keyword = tokenizedAction.nextToken();
    	actionResponse = new ActionResponse();
    	actionResponse.setActingCharacter(session.getCharacter());
    	Area location;
		String param1 = null;
		
		if (tokenizedAction.hasMoreTokens()) {
			param1 = tokenizedAction.nextToken();
		}
		
		switch (keyword.toLowerCase()) {
			case "describe":
			case "desc":
				location = session.getCharacter().getLocation();
				actionResponse.setActingCharacterDescription(location.describeRoom(session.getCharacter()));
				break;
			case "look":
				location = session.getCharacter().getLocation();
				if (param1 == null) {
					throw new DeadlyDinnerPartyException("Look at what?");
				}
				Exit exit = location.getExit(Exit.getDirection(param1));
				if (exit != null || param1.equalsIgnoreCase("Secret")) {
					Area exitLoc = exit.getExitArea(location);
					
					if (exitLoc == null) {
						throw new DeadlyDinnerPartyException ("There is no exit " + exit);
					}
					if (exit.getStatus() != Exit.ExitStatus.OPEN && exit.getStatus() != Exit.ExitStatus.BASHED) {
						throw new DeadlyDinnerPartyException ("The exit " + exit + " to " + exitLoc.getName() + " is closed, so you can't see in.");	
					}
					actionResponse.setActingCharacterDescription(exitLoc.describeRoom(session.getCharacter()));
				} else if (location.getCharacter(param1) != null) {
					GameCharacter character = location.getCharacter(param1);
					actionResponse.setActingCharacterDescription(character.getDescription());
				} else if (location.getChest(param1) != null) {
					Chest chest = location.getChest(param1);
					if (chest.isLocked()) {
						throw new DeadlyDinnerPartyException(chest.getName() + " is locked.");
					}
					String desc = "The chest contains:";
					for (Item i : chest.getContents()) {
						desc = desc + "\n  " + i.getName() + " - " + i.getDescription();
					}
					actionResponse.setActingCharacterDescription(desc);
				} else {
					throw new DeadlyDinnerPartyException ("There is nothing in the room called " + param1 + " to look at.");
				}
				break;
			default:
				break;
		}
        actionComplete = true;
        return actionResponse;
    }
	
    public ActionResponse getActionResponse() {
		return actionResponse;
	}
    
    public Set<String> getKeywords() {
        return keywords;
    }
}